/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

/**
 *
 * <p>
 *     注册时机：BeanFactoryPostProcessor 并不直接负责注册 bean 定义。它的主要职责是在所有 bean 定义已经被加载到容器中之后，
 *     但在任何 bean 实例被创建之前，修改这些 bean 定义。
 *
 *     实例化时机：BeanFactoryPostProcessor 实例通常由 Spring 容器自动检测并实例化。如果你通过组件扫描或者显式地将其实现类声明为一个 bean，
 *     Spring 会在启动阶段自动发现并初始化它(实际上是在容器刷新阶段 refresh()，invokeBeanFactoryPostProcessors)。
 *
 *     方法调用时机：一旦所有的 BeanFactoryPostProcessor 实例被实例化，Spring 就会调用它们的 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法。这发生在 Spring 应用上下文刷新过程中的早期阶段，
 *     具体来说，在所有的单例 beans 被实例化之前。
 * </p>
 *
 * Factory hook that allows for custom modification of an application context's
 * bean definitions, adapting the bean property values of the context's underlying
 * bean factory.
 * <br> 工厂钩子，允许对应用程序上下文bean定义进行自定义修改，调整上下文底层bean工厂的bean属性值。
 *
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context. See
 * {@link PropertyResourceConfigurer} and its concrete implementations for
 * out-of-the-box solutions that address such configuration needs.
 * <br> 用于自定义配置文件，针对系统管理员，覆盖应用程序上下文配置的bean属性。
 *
 * <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 * <br> BeanFactoryPostProcessor 可能与bean定义交互，修改bean定义，但从不修改bean实例。
 * 如果修改bean实例，这样做可能会导致过早的bean实例化，违反容器并导致意外的副作用。
 * 如果需要bean实例交互，请考虑实现 BeanPostProcessor。
 *
 * <h3>Registration</h3>
 * <h3>注册</h3>
 * <p>An {@code ApplicationContext} auto-detects {@code BeanFactoryPostProcessor}
 * beans in its bean definitions and applies them before any other beans get created.
 * A {@code BeanFactoryPostProcessor} may also be registered programmatically
 * with a {@code ConfigurableApplicationContext}.
 * <br> ApplicationContext 在其bean定义中自动检测 BeanFactoryPostProcessor bean定义，并在创建任何其他bean之前应用它们。
 * <br> ApplicationContext 会自动检测 BeanFactoryPostProcessor bean定义，并应用这些bean定义。
 * 可以通过编程方式，在ConfigurableApplicationContext中注册BeanFactoryPostProcessor。
 *
 * <h3>Ordering</h3>
 * <h3>排序</h3>
 * <p>{@code BeanFactoryPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanFactoryPostProcessor} beans that are registered programmatically
 * with a {@code ConfigurableApplicationContext} will be applied in the order of
 * registration; any ordering semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanFactoryPostProcessor} beans.
 * <br> BeanFactoryPostProcessor beans 在ApplicationContext中自动检测到的将根据 PriorityOrdered 和 Ordered 语义进行排序。
 * <br> 在ConfigurableApplicationContext以编程方式注册的 BeanFactoryPostProcessor beans 将按注册顺序应用，此时对于通过实现 PriorityOrdered 或 Ordered 接口表达的任何排序语义，将被忽略。
 * <br> 另外，对于 BeanFactoryPostProcessor beans，@Order 注解将被忽略。
 *
 *
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * <br> 在标准初始化后修改应用程序上下文的内部bean工厂。所有bean定义都将已加载，但尚未实例化任何bean。
	 * <br> 允许覆盖或添加属性，即使为急切初始化的bean。
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
